from absl import app, flags
import pandas
import datetime
import requests
import os
import pandas as pd
from coin.base.datetime_util import to_timestamp_int
from coin2.service.strategy import trading_summary_service_pb2 as tss_pb2
from xunkemgmt_client.client.api_client import XunkemgmtClient


def daterange(start_date, end_date):
  for n in range(int((end_date - start_date).days) + 1):
    yield start_date + datetime.timedelta(n)


def get_strategy_info(trader, start_date, end_date):
  print("**************************")
  print(f"Trader     : {trader}")
  print(f"Start Date : {start_date}")
  print(f"End Date   : {end_date}")
  print("**************************")

  start_ts = to_timestamp_int(datetime.datetime.strptime(start_date, "%Y-%m-%d"))
  end_ts = to_timestamp_int(datetime.datetime.strptime(end_date, "%Y-%m-%d") + datetime.timedelta(days=1))

  with XunkemgmtClient() as client:
    response = client.query_trading_summary_interval_histories(
      tss_pb2.QueryTradingSummaryIntervalHistoriesRequestProto(
        start_timestamp=start_ts,
        end_timestamp=end_ts,
        business_units=['coin', 'coinfof', 'prex', 'day1mm', 'extday1mm', 'digitalfund'],
        exchanges=["Binance"],
        market_types=["Spot"],
        traders=trader.split(","),
      )
    )
  data_list = []
  for proto in response.histories:
    summary_info = proto.summary_info
    summary = proto.summary
    data = {
      "trading_date": datetime.datetime.strptime(str(summary_info.trading_date), "%Y%m%d").strftime("%Y-%m-%d"),
      "owner": summary_info.owner,
      "maker_pq": summary.turnover_maker_mark,
      "taker_pq": summary.turnover_taker_mark,
    }
    data_list.append(data)

  df = pd.DataFrame(data_list)
  df.drop_duplicates(inplace=True)
  df = df.groupby(["owner", "trading_date"]).sum().reset_index()

  price_data = []
  start_timestamp = datetime.datetime.strptime(start_date, "%Y-%m-%d")
  end_timestamp = datetime.datetime.strptime(end_date, "%Y-%m-%d")
  for td_timestamp in daterange(start_timestamp, end_timestamp):
    price = get_bnb_price(td_timestamp)
    price_data.append({'trading_date': td_timestamp.strftime("%Y-%m-%d"), 'bnb_price': price})
  bnb_price_df = pandas.DataFrame(price_data).ffill()
  total_df = df.merge(bnb_price_df, on='trading_date', how='left')
  # jingyuan: VIP9 Spot taker + burn bnb 3bp, bns referal rebate 40% actual fee
  total_df['bnb_amt'] = total_df.taker_pq / total_df.bnb_price * 3e-4 * 0.4
  pandas.options.display.float_format = '{:,.4f}'.format
  print("\n@@@@Result")
  total_df.to_csv(os.path.expanduser(f"~/binance_spot_{trader}_{start_date}_{end_date}.csv"),
                  index=False)
  print(total_df.groupby('owner').bnb_amt.sum())
  # print(result + "\nAlso send to slack.....")
  # os.system(f"noti -s @taekwon '```{result}```'")
  print("Complete.")


def get_bnb_price(trading_datetime):
  timestamp = int(trading_datetime.timestamp() * 1000)
  start_timestamp = timestamp + 2 * 3600 * 1000
  end_timestamp = start_timestamp + 10 * 60 * 1000
  addr = "https://api.binance.com/api/v3/aggTrades?symbol=BNBUSDT&startTime={}&endTime={}".format(
          start_timestamp, end_timestamp)
  print(addr)
  pq_data = requests.get(addr).json()
  pq_sum = 0.0
  q_sum = 0.0
  for row in pq_data:
    pq_sum += (float(row['p']) * float(row['q']))
    q_sum += float(row['q'])
  try:
    vwap = pq_sum / q_sum
  except:
    vwap = float('nan')
  return vwap


def init_flags():
  pandas.set_option('display.width', 200)
  pandas.set_option('display.max_rows', 200)
  flags.DEFINE_string('trader', 'taekwon', 'trader, comma sep')
  flags.DEFINE_string('start_date', '2020-04-06', 'start date')
  flags.DEFINE_string('end_date', '2020-04-06', 'end date')


def main(_):
  get_strategy_info(flags.FLAGS.trader, flags.FLAGS.start_date, flags.FLAGS.end_date)


if __name__ == '__main__':
  init_flags()
  app.run(main)
